#include "usart-board.h"
#include "tremo_gpio.h"
#include "tremo_rcc.h"
#include "system.h"



uint16_t AtCommandState =0;
uint8_t AtCommandBuf[AT_COMMAND_BUFFER_LEN] = {0};


__IO uint8_t LPUART_RxBuff[LPUART_FIFO_BUFFER_SIZE] = {0};
__IO uint8_t UART1_RxBuff[UART1_FIFO_BUFFER_SIZE] = {0};

#if defined(CONFIG_DTU_485)
UART_INFO_STR UartPortAddr[SYS_UART_CNT] = {0};
#endif

//log串口和 DEBUG串口
void Uart0Init(UART_INFO_STR *pUartInfo)
{
    // uart0
    gpio_set_iomux(GPIOB, GPIO_PIN_0, 1);   //UART0_RXD
    gpio_set_iomux(GPIOB, GPIO_PIN_1, 1);   //UART0_TXD

    /* uart config struct init */
    uart_config_t uart_config;
    uart_config_init(&uart_config);
    uart_config.baudrate = UART_BAUDRATE_115200;
//    uart_config.fifo_mode = ENABLE;
    uart_init(UART0, &uart_config);

//    uart_set_rx_fifo_threshold(UART0, UART_RX_FIFO_LEVEL_1_4);
    uart_config_interrupt(UART0, UART_INTERRUPT_RX_DONE,ENABLE);
    uart_clear_interrupt(UART0, UART_INTERRUPT_RX_DONE);

    NVIC_SetPriority(UART0_IRQn, 2);
    NVIC_EnableIRQ(UART0_IRQn);
    uart_cmd(UART0, ENABLE);
}

#if defined(CONFIG_DTU_485)
//485串口
void Uart1Init(UART_INFO_STR *pUartInfo)
{
    // uart0
    gpio_set_iomux(GPIOA, GPIO_PIN_4, 2);   //GPIO4 UART1 TX
    gpio_set_iomux(GPIOA, GPIO_PIN_5, 2);   //GPIO5 UART1 RX
    gpio_init(GPIOA, GPIO_PIN_5, GPIO_MODE_INPUT_PULL_UP);

    /* uart config struct init */
    uart_config_t uart_config;
    uart_config_init(&uart_config);
    uart_config.baudrate = SystemParmData.baudRate;
    uart_config.parity = SystemParmData.parityMode;
    if (SystemParmData.dataWidth == 5) {
        uart_config.data_width = UART_DATA_WIDTH_5;
    } else if (SystemParmData.dataWidth == 6) {
        uart_config.data_width = UART_DATA_WIDTH_6;
    } else if (SystemParmData.dataWidth == 7) {
        uart_config.data_width = UART_DATA_WIDTH_7;
    } else {
        uart_config.data_width = UART_DATA_WIDTH_8;
    }

    uart_config.stop_bits = (SystemParmData.stopBit == 2) ? UART_STOP_BITS_2 : UART_STOP_BITS_1;
    //    uart_config.fifo_mode = ENABLE;
    uart_init(UART1, &uart_config);

//    uart_set_rx_fifo_threshold(UART1, UART_RX_FIFO_LEVEL_1_4);
    uart_config_interrupt(UART1, UART_INTERRUPT_RX_DONE,ENABLE);
    uart_clear_interrupt(UART1, UART_INTERRUPT_RX_DONE);

    NVIC_SetPriority(UART1_IRQn, 1);
    NVIC_EnableIRQ(UART1_IRQn);

    uart_cmd(UART1, ENABLE);

    pUartInfo->index = 1;
    FIFO_S_Init(&pUartInfo->rxBuffCtrl, (void*)UART1_RxBuff, sizeof(UART1_RxBuff));
}

//RS232串口
void LpuartInit(UART_INFO_STR *pUartInfo)
{
    lpuart_init_t lpuart_init_cofig;
    uart_config_t uart_config;

    rcc_enable_peripheral_clk(RCC_PERIPHERAL_GPIOD, true);
    // set iomux
    gpio_set_iomux(GPIOC, GPIO_PIN_15, 2); // LPUART_TX:GP47

    gpio_init(GPIOD, GPIO_PIN_12, GPIO_MODE_INPUT_FLOATING);
    gpio_set_iomux(GPIOD, GPIO_PIN_12, 2); // LPUART_RX:GP60

    // lpuart init
    lpuart_deinit(LPUART);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_LPUART, true);
    lpuart_init_cofig.baudrate         = 9600;
    lpuart_init_cofig.data_width       = LPUART_DATA_8BIT;
    lpuart_init_cofig.parity           = LPUART_PARITY_NONE;
    lpuart_init_cofig.stop_bits        = LPUART_STOP_1BIT;
    lpuart_init_cofig.low_level_wakeup = false;
    lpuart_init_cofig.start_wakeup     = false;
    lpuart_init_cofig.rx_done_wakeup   = true;
    lpuart_init(LPUART, &lpuart_init_cofig);

    lpuart_config_rts(LPUART, false);
    lpuart_config_cts(LPUART, false);


    lpuart_config_tx(LPUART, true);
    lpuart_config_rx(LPUART, true);

    lpuart_config_interrupt(LPUART, LPUART_CR1_RX_DONE_INT, ENABLE);

    lpuart_clear_rx_status(LPUART, LPUART_SR0_RX_DONE_STATE);

    NVIC_SetPriority(LPUART_IRQn, 2);
    NVIC_EnableIRQ(LPUART_IRQn);

    pUartInfo->index = 0;
    FIFO_S_Init(&pUartInfo->rxBuffCtrl, (void*)LPUART_RxBuff, sizeof(LPUART_RxBuff));

}

#endif
void ReEnableUart(uart_t* uart)
{
    uart_config_t uart_config;
    uart_config_init(&uart_config);
    uart_config.baudrate = SystemParmData.baudRate;
    uart_config.parity = SystemParmData.parityMode;
    if (SystemParmData.dataWidth == 5) {
        uart_config.data_width = UART_DATA_WIDTH_5;
    } else if (SystemParmData.dataWidth == 6) {
        uart_config.data_width = UART_DATA_WIDTH_6;
    } else if (SystemParmData.dataWidth == 7) {
        uart_config.data_width = UART_DATA_WIDTH_7;
    } else {
        uart_config.data_width = UART_DATA_WIDTH_8;
    }

    uart_config.stop_bits = (SystemParmData.stopBit == 2) ? UART_STOP_BITS_2 : UART_STOP_BITS_1;
    //    uart_config.fifo_mode = ENABLE;
    uart_init(uart, &uart_config);
    uart_clear_interrupt(uart, UART_INTERRUPT_RX_DONE);

    uart_cmd(uart, ENABLE);
}

void UartInit(void)
{
#if defined(CONFIG_DTU_485)
    LpuartInit(&UartPortAddr[0]);			//Lpuart RS232串口
    Uart1Init(&UartPortAddr[1]);			//串口1 485串口
#endif
}

void Uart0IrqProcess(void)
{
	uint8_t data = 0;
    if(uart_get_interrupt_status(UART0, UART_INTERRUPT_RX_DONE))
    {
        data = uart_receive_data(UART0);
        uart_clear_interrupt(UART0, UART_INTERRUPT_RX_DONE);
        if((AtCommandState&0x8000)==0)  				//还未收完
        {
            if(AtCommandState&0x4000)   				//若之前收到了0x0D
            {
                if(data!=0x0a)	      					//接收到的不是0x0A，则标识又可能数据内容是0x0D
                {
                  AtCommandBuf[AtCommandState&0X3FFF] = data ;
				  AtCommandState &= 0xBFFF;				//清除接收到的0x0D标识
                  AtCommandState++;
                }
                else
                {
                  AtCommandState|=0x8000;				//接受完成
                  AtCommandBuf[AtCommandState&0X3FFF]=0 ;
                }
            }
            else
            {
                if(data==0x0d)
                {
                    AtCommandState|=0x4000;
                }
                else
                {
                    AtCommandBuf[AtCommandState&0X3FFF]=data ;
                    AtCommandState++;
                    if((AtCommandState&0X3FFF)>(AT_COMMAND_BUFFER_LEN-1))
                    {
                        AtCommandState = 0;
                    }
                }
            }
        }
    }
}

#if defined(CONFIG_DTU_485)
void Uart1IrqProcess(void)
{
    UART_INFO_STR *pUart = &UartPortAddr[1];
    if(uart_get_interrupt_status(UART1, UART_INTERRUPT_RX_DONE))
    {
        // UartSendData(UART_INDEX_DEBUG, (uint8_t *)"uart1 recv: ", strlen("recv: "));
        while (uart_get_flag_status(UART1, UART_FLAG_RX_FIFO_EMPTY) != SET) {
            uint8_t data = uart_receive_data(UART1);
            // char buf[64] = {0};
            // sprintf(buf, " 0x%02x", data);
            // UartSendData(UART_INDEX_DEBUG, (uint8_t *)buf, strlen(buf));
            FIFO_S_Put(&pUart->rxBuffCtrl, data);
        }
        uart_clear_interrupt(UART1, UART_INTERRUPT_RX_DONE);
        // UartSendData(UART_INDEX_DEBUG, (uint8_t *)"\r\n", strlen("\r\n"));
    }
}



void LpuartIrqProcess(void)
{
    UART_INFO_STR *pUart = &UartPortAddr[0];
	uint8_t data = 0;
    if(lpuart_get_rx_status(LPUART, LPUART_SR0_RX_DONE_STATE))
    {
        data = lpuart_receive_data(LPUART);
        lpuart_clear_rx_status(LPUART, LPUART_SR0_RX_DONE_STATE);
        FIFO_S_Put(&pUart->rxBuffCtrl, data);
    }
}
#endif

/*
 * @Functions:   void UartSendData(uint8_t UartIndex,const uint8_t *p, uint32_t len)
 * @Description: 发送一定长度串口数据
 * @Parameters:  MONE
 * @Return:      NONE
 */
void UartSendData(uint8_t portIndex, const uint8_t *p, uint32_t len)
{
    uint32_t i = 0;

    if(portIndex == UART_INDEX_DEBUG)
    {
        for(i = 0;i < len ;i++)
        {
            uart_send_data(UART0, p[i]);
            while (!uart_get_flag_status(UART0,UART_FLAG_TX_FIFO_EMPTY)) ;
        }
    }
#if defined(CONFIG_DTU_485)
    else if(portIndex == UART_INDEX_485)
    {
        for(i = 0;i < len ;i++)
        {
            uart_send_data(UART1, p[i]);
            while (!uart_get_flag_status(UART1,UART_FLAG_TX_FIFO_EMPTY)) ;
        }
    }
    else if(portIndex == UART_INDEX_RS232)
    {
        for(i = 0;i < len ;i++)
        {
            lpuart_send_data(LPUART, p[i]);
            while (!lpuart_get_tx_done_status(LPUART)) ;
            lpuart_clear_tx_done_status(LPUART);
        }
    }
#endif
}


#if defined(CONFIG_DTU_485)
int UsartGetOneData(int portIndex, uint8_t *pData)
{
    UART_INFO_STR *pUart = &UartPortAddr[portIndex];

    return FIFO_S_Get(&pUart->rxBuffCtrl, pData);
}


void UsartFifoFlush(int portIndex)
{
	UART_INFO_STR *pUart = &UartPortAddr[portIndex];
	FIFO_S_Flush(&pUart->rxBuffCtrl);
}
#endif
